package com.engine.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class ListMapAndJson {

    public static String ListMap2Geojson(List<Map<String,Object>> lmap) {
        List<Map<String, Object>> features = new ArrayList<Map<String, Object>>();
        Map<String, Object> root = new HashMap<>();
        for (Map<String, Object> map : lmap) {
            Map<String, Object> feature = new HashMap<>();
            feature.put("type", "Feature");
            if(map.get("geojson")==null)
            {
                feature.put("geometry", JSONObject.parseObject((String) map.get("geom")));
                map.remove("geom");
            }
            else{
                feature.put("geometry", JSONObject.parseObject((String) map.get("geojson")));
                map.remove("geojson");
            }
            feature.put("properties", map);
            features.add(feature);
        }
        root.put("type", "FeatureCollection");
        root.put("features", features);
        JSONObject jsonObject = new JSONObject(root);
        return JSONObject.toJSONString(jsonObject, SerializerFeature.WriteNullStringAsEmpty);
    }

    public static JSONObject ListMap2GeojsonObject(List<Map<String,Object>> lmap) {
        if(lmap==null)
            return null;
        List<Map<String, Object>> features = new ArrayList<Map<String, Object>>();
        Map<String, Object> root = new HashMap<>();
        for (Map<String, Object> map2 : lmap) {
            Map<String, Object> map= new HashMap<>();
            map.putAll(map2);
            Map<String, Object> feature = new HashMap<>();
            feature.put("type", "Feature");
            if(map.get("geojson")==null)
            {
                feature.put("geometry", JSONObject.parseObject((String) map.get("geom")));
                map.remove("geom");
            }
            else{
                feature.put("geometry", JSONObject.parseObject((String) map.get("geojson")));
                map.remove("geojson");
            }
            feature.put("properties", map);
            features.add(feature);
        }
        root.put("type", "FeatureCollection");
        root.put("features", features);
        return new JSONObject(root);
    }

    public static String GeojsonAddMapInRoot(String geojson,Map<String,Object> map) {
        JSONObject jsonObject=JSONObject.parseObject(geojson);
        Map<String, Object> mp= (Map<String, Object>)jsonObject;
        mp.put("statistical",map);
        List<Map<String, Object>> features = new ArrayList<Map<String, Object>>();
        return JSONObject.toJSONString(jsonObject, SerializerFeature.WriteNullStringAsEmpty);
    }
    public static String GeojsonMergeFeatures(String bascGeojson,String anotherGeojson,String anotherName) {
        Map<String, Object> mp1;
        Map<String, Object> statistical;
        JSONObject jsonObject2=JSONObject.parseObject(anotherGeojson);
        JSONArray features2=jsonObject2.getJSONArray("features");
        List<Map<String,Object>> lm=new ArrayList<>();
        for (Object feature:features2) {
            Map<String, Object> mp= (Map<String, Object>)feature;
            lm.add(mp);
        }
        if(bascGeojson.equals(""))
        {
            mp1=new HashMap<>();
            statistical=new HashMap<>();
            statistical.put(anotherName+"_count",features2.size());
            mp1.put("type", "FeatureCollection");
            mp1.put("features", lm);
            mp1.put("statistical", statistical);
        }
        else
        {
            JSONObject jsonObject1=JSONObject.parseObject(bascGeojson);
            mp1=(Map<String, Object>)jsonObject1;
            ((List<Map<String, Object>>)mp1.get("features")).addAll(lm);
            ((Map<String, Object>)mp1.get("statistical")).put(anotherName+"_count",features2.size());
        }
        JSONObject jsonObject = new JSONObject(mp1);
        return JSONObject.toJSONString(jsonObject, SerializerFeature.WriteNullStringAsEmpty);
    }
    public static List<Map<String,Object>> Geojson2ListMap(String geojson)
    {
        JSONObject jsonObject=JSONObject.parseObject(geojson);
        JSONArray features=jsonObject.getJSONArray("features");
        List<Map<String,Object>> lm=new ArrayList<>();
        for (Object feature:features) {
            JSONObject properties=((JSONObject)feature).getJSONObject("properties");
            String geometry=((JSONObject)feature).getJSONObject("geometry").toString();
            Map<String, Object> mp= (Map<String, Object>)properties;
            mp.put("geom",geometry);
            lm.add(mp);
        }
        return lm;
    }
    public static String ListMap2GeojsonWithStatistics(List<Map<String,Object>> lmap, Map<String,Object> statisticsMap) {
        List<Map<String, Object>> features = new ArrayList<Map<String, Object>>();
        Map<String, Object> root = new HashMap<>();
        for (Map<String, Object> map : lmap) {
            Map<String, Object> feature = new HashMap<>();
            feature.put("type", "Feature");
            feature.put("geometry", JSONObject.parseObject((String) map.get("geojson")));
            map.remove("geojson");
            feature.put("properties", map);
            features.add(feature);
        }
        root.put("type", "FeatureCollection");
        root.put("features", features);
        root.put("statistics", statisticsMap);
        JSONObject jsonObject = new JSONObject(root);

        return JSONObject.toJSONString(jsonObject, SerializerFeature.WriteNullStringAsEmpty);
    }

    public static String GeojsonChangeNumColumns(String geoJson, String intCloumns,String floatCloumns) {
        String[] intCloumnArry = intCloumns.split(",");
        String[] floatCloumnArry = floatCloumns.split(",");
        List<Map<String, Object>> mapList = Geojson2ListMap(geoJson);
        for (Map<String, Object> map : mapList) {
            for (String intCloumn : intCloumnArry) {
                if(!map.containsKey(intCloumn))
                    continue;
                try {
                    Long l = Long.parseLong(map.get(intCloumn).toString());
                    map.put(intCloumn, l);
                } catch (Exception e) {
                    map.put(intCloumn, null);
                }
            }
            for (String floatCloumn : floatCloumnArry) {
                if(!map.containsKey(floatCloumn))
                    continue;
                try {
                    Double l = Double.parseDouble(map.get(floatCloumn).toString());
                    map.put(floatCloumn, l);
                }
                catch (Exception e) {
                    map.put(floatCloumn, null);
                }
            }
        }
        return ListMap2Geojson(mapList);
    }

    public static String getUUID32(){

        return UUID.randomUUID().toString().toLowerCase();

    }
}
